package com.ruicar.afs.cloud.workflow.greatwall.component;

import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.workflow.greatwall.dto.GwtRequest;
import com.ruicar.afs.cloud.workflow.greatwall.enums.GwtMsgType;
import com.ruicar.afs.cloud.workflow.greatwall.enums.GwtObjectCode;
import com.ruicar.afs.cloud.workflow.greatwall.exception.FlowProcessException;
import com.ruicar.afs.cloud.workflow.greatwall.processor.GwfObjectCodeProcessor;
import com.ruicar.afs.cloud.workflow.greatwall.processor.GwtFlowProcessor;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@AllArgsConstructor
public class GwtProcessComponent {
    private static final Map<GwtMsgType, GwtFlowProcessor> GWT_FLOW_MSG_PROCESSOR_MAP = new HashMap<>();
    private static final Map<String, GwfObjectCodeProcessor> GWT_FLOW_OBJ_PROCESSOR_MAP = new HashMap<>();
    private final List<GwtFlowProcessor> gwtFlowMsgProcessorList;
    private final List<GwfObjectCodeProcessor> gwtFlowObjProcessorList;




    @PostConstruct
    public void initProcess() {
        GWT_FLOW_MSG_PROCESSOR_MAP.putAll(gwtFlowMsgProcessorList.stream().collect(Collectors.toMap(GwtFlowProcessor::msgType, Function.identity())));
        GWT_FLOW_OBJ_PROCESSOR_MAP.putAll(gwtFlowObjProcessorList.stream().collect(Collectors.toMap(GwfObjectCodeProcessor::processKey, Function.identity())));
    }

    private static class DefaultFlowProcessor implements GwtFlowProcessor {
        @Override
        public void checkException(String serviceId, String bizDataId) {

        }

        GwtMsgType gwtMsgType;

        public DefaultFlowProcessor(GwtMsgType gwtMsgType) {
            this.gwtMsgType = gwtMsgType;
        }

        @Override
        public GwtMsgType msgType() {
            return gwtMsgType;
        }

        @Override
        public String process(GwtRequest req) {
            throw new FlowProcessException(HttpStatus.INTERNAL_SERVER_ERROR, "{\"code\":\"0\",\"message\":\"server error\"}");
        }
    }

    private static class DefaultFlowObjectProcessor implements GwfObjectCodeProcessor {
        public DefaultFlowObjectProcessor() {
        }

        @Override
        public void checkException(String serviceId, String bizDataId) {

        }

        GwtMsgType gwtMsgType;
        GwtObjectCode gwtObjectCode;

        public DefaultFlowObjectProcessor(GwtMsgType gwtMsgType, GwtObjectCode gwtObjectCode) {
            this.gwtMsgType = gwtMsgType;
            this.gwtObjectCode = gwtObjectCode;
        }

        @Override
        public GwtMsgType belongMsg() {
            return this.gwtMsgType;
        }

        @Override
        public GwtObjectCode objectCode() {
            return this.gwtObjectCode;
        }

        @Override
        public String process(GwtRequest request) {
            throw new FlowProcessException(HttpStatus.INTERNAL_SERVER_ERROR, "{\"code\":\"0\",\"message\":\"server error\"}");
        }
    }


    public static GwtFlowProcessor gwtFlowMsgProcessor(GwtMsgType gwtMsgType) {
        return GWT_FLOW_MSG_PROCESSOR_MAP.getOrDefault(gwtMsgType, new DefaultFlowProcessor(gwtMsgType));
    }

    public static GwfObjectCodeProcessor gwtObjProcessor(GwtMsgType gwtMsgType, GwtObjectCode gwtObjectCode) {
        return GWT_FLOW_OBJ_PROCESSOR_MAP.getOrDefault(MessageFormat.format("{0}-{1}", AfsEnumUtil.key(gwtMsgType), AfsEnumUtil.key(gwtObjectCode)), new DefaultFlowObjectProcessor(gwtMsgType, gwtObjectCode));
    }

    public static GwfObjectCodeProcessor gwtObjProcessor(String processType) {
        return GWT_FLOW_OBJ_PROCESSOR_MAP.getOrDefault(processType, new DefaultFlowObjectProcessor());
    }
}
